package com.fastCms.business.bim.manage.impl;

import com.fastCms.business.bim.daos.*;
import com.fastCms.business.bim.enums.DeviceTypeEnum;
import com.fastCms.business.bim.enums.ListenBusiType;
import com.fastCms.business.bim.manage.DeviceManageService;
import com.fastCms.business.bim.pojo.dto.RankDTO;
import com.fastCms.business.bim.pojo.entity.*;
import com.fastCms.business.bim.pojo.po.*;
import com.fastCms.business.bim.pojo.vo.*;
import com.fastCms.business.bim.service.DeviceFiledValueService;
import com.fastCms.business.bim.service.DeviceService;
import com.fastCms.business.bim.service.DeviceTypeService;
import com.fastCms.business.frame.constant.CommonConst;
import com.fastCms.business.frame.pojo.PageParam;
import com.fastCms.business.frame.response.ApiResponse;
import com.fastCms.business.frame.response.ResponseUtil;
import com.fastCms.business.frame.utils.CommonsUtil;
import com.fastCms.business.frame.utils.opc.DateUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Transactional(rollbackFor = Exception.class)
@Component
@Slf4j
public class DeviceManageServiceImpl implements DeviceManageService {
    @Autowired
    private DeviceTypeService deviceTypeServiceImpl;

    @Autowired
    private DeviceService deviceServiceImpl;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private DataListenMapper dataListenMapper;

    @Autowired
    private FiledsMapper filedsMapper;

    @Autowired
    private DeviceFiledValueService deviceFiledValueServiceImpl;
    @Autowired
    private AreaMapper areaMapper;


    @Autowired
    private StringRedisTemplate redis;

    @Autowired
    private DataProdMapper dataProdMapper;

    @Override
    public PageInfo<DeviceInfoVO> deviceList(PageParam<DeviceListPO> pageParam) {
        DeviceListPO queryFields = pageParam.getQueryFields();
        PageInfo<DeviceInfoVO> result =
            PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize())
                .doSelectPageInfo(() ->
                    deviceMapper.showList(queryFields));
        return result;
    }

    @Override
    public List<DeviceFiledsVO> getDeviceFields(Integer deviceTypeId) {
        List<DeviceFiledsVO> fields = filedsMapper.getDeviceFields(deviceTypeId);
        return fields;
    }

    @Override
    public List<ListenDataDetailVO> getListenDetailList(String busiType) {
        if (ListenBusiType.TSP.getCode().equals(busiType)) {
            List<ListenDataDetailVO> result = dataListenMapper.showListenDetailList(DeviceTypeEnum.TSP.getCode());
            return result;
        } else if (ListenBusiType.PM25.getCode().equals(busiType) || ListenBusiType.PM10.getCode().equals(busiType)) {
            List<ListenDataDetailVO> result = dataListenMapper.showListenDetailList(DeviceTypeEnum.AIR_QT.getCode());
            return result;
        }
        return null;
    }


    @Override
    public List<DeviceType> getDeviceTypes() {
        List<DeviceType> devicetypes = deviceTypeServiceImpl.findByDevices();
        return devicetypes;
    }

    @Override
    public Boolean deleteDevice(Integer deviceId) {
        Device device = deviceServiceImpl.findById(deviceId);
        if (null != device) {
            device.setState(CommonConst.STATE.INVALID);
            boolean b = deviceServiceImpl.updateById(device);
            return b;
        }
        return true;
    }

    @Override
    public DeviceInfoVO deviceInfo(Integer deviceId) {
        DeviceInfoVO deviceInfo = deviceMapper.showInfo(deviceId);
//if (deviceInfo != null && deviceInfo.getWorkduceId() != null) {
//    Workduce workduce = workduceServiceImpl.getById(deviceInfo.getWorkduceId());
//    deviceInfo.setProduce(workduce.getProduce());
//}
        List<DeviceFiledsValueVO> filedValues = filedsMapper.getDeviceFieldsValue(deviceInfo.getDeviceTypeId(), deviceId);
        deviceInfo.setFiledsValueList(filedValues);
        return deviceInfo;
    }

    @Override
    public ApiResponse<Boolean> addDevice(DeviceAddPO deviceAddPO) {
        if (StringUtils.isNotBlank(deviceAddPO.getDeviceCode())) {
            Device device = deviceServiceImpl.findByDeviceCode(deviceAddPO.getDeviceCode());
            if (null != device) {
                return ResponseUtil.fail("该设备编号已经存在!");
            }
        }
        Device device = new Device();
        CommonsUtil.initEntity(device);
        BeanUtils.copyProperties(deviceAddPO, device);
        boolean result = deviceServiceImpl.save(device);
        Integer deviceId = device.getId();

        List<DeviceFiledsValueVO> fileds = deviceAddPO.getFiledsValueList();

        if (CollectionUtils.isNotEmpty(fileds)) {
            List<DeviceFiledValue> valueList = fileds.stream().map(filed -> {
                DeviceFiledValue deviceFiledValue = new DeviceFiledValue();
                CommonsUtil.initEntity(deviceFiledValue);
                deviceFiledValue.setDeviceId(deviceId);
                deviceFiledValue.setFiledCode(filed.getFiledCode());
                deviceFiledValue.setFiledValue(filed.getFiledValue());
                return deviceFiledValue;
            }).collect(Collectors.toList());
            deviceFiledValueServiceImpl.saveOrUpdateBatch(valueList);
        }

        return ResponseUtil.success(result);
    }

    @Override
    public ApiResponse<Boolean> updateDevice(DeviceUpdatePO deviceUpdatePO) {
        Integer deviceId = deviceUpdatePO.getId();
        Device device = deviceServiceImpl.findById(deviceId);
        if (null == device) {
            return ResponseUtil.fail("查无设备!");
        }
        if (!deviceUpdatePO.getDeviceCode().equals(device.getDeviceCode())) {
            Device oldDevice = deviceServiceImpl.findByDeviceCode(deviceUpdatePO.getDeviceCode());
            if (null != oldDevice) {
                return ResponseUtil.fail("该设备编号已经存在!");
            }
        }

        device = new Device();
        BeanUtils.copyProperties(deviceUpdatePO, device);
        boolean result = deviceServiceImpl.updateById(device);

        List<DeviceFiledsValueVO> filedsValueList = deviceUpdatePO.getFiledsValueList();

        if (CollectionUtils.isNotEmpty(filedsValueList)) {
            filedsValueList.forEach(fileds -> {
                DeviceFiledValue deviceFiledValue = deviceFiledValueServiceImpl.findByDeviceIdAndCode(deviceId, fileds.getFiledCode());
                if (null != deviceFiledValue) {
                    deviceFiledValue.setFiledValue(fileds.getFiledValue());
                    deviceFiledValueServiceImpl.updateById(deviceFiledValue);
                } else {
                    deviceFiledValue = new DeviceFiledValue();
                    CommonsUtil.initEntity(deviceFiledValue);
                    deviceFiledValue.setFiledValue(fileds.getFiledValue());
                    deviceFiledValue.setDeviceId(deviceId);
                    deviceFiledValue.setFiledCode(fileds.getFiledCode());
                    deviceFiledValueServiceImpl.save(deviceFiledValue);
                }
            });
        }
        return ResponseUtil.success(result);
    }

    @Override
    public List<AirVO> getAirValue() {

// todo 测试数据，临时用1004来表示空气检测数据
        List<DataListen> dataListens = dataListenMapper.getActualByDeviceId(1004L);

        List<AirVO> AirVos = dataListens.stream().map(dataListen -> {
            AirVO air = new AirVO();
            air.setAqi(dataListen.getAqi());
            air.setPm2p5(dataListen.getPm25());
            air.setPm10(dataListen.getPm10());
            return air;
        }).collect(Collectors.toList());

        return AirVos;
    }

    private List<AirInfoVO> getAirList(Map<String, List<String>> pm) {
        List<AirInfoVO> airInfoVOs = new ArrayList<>();
        pm.forEach((k, v) -> {
            AirInfoVO airInfoVO = getAirInfo(k, v);
            airInfoVOs.add(airInfoVO);
        });
        sortArr(airInfoVOs);
        return airInfoVOs;
    }

    private void sortArr(List<AirInfoVO> airInfoVOS) {
        Collections.sort(airInfoVOS, new Comparator<AirInfoVO>() {
            @Override
            public int compare(AirInfoVO air1, AirInfoVO air2) {
                return (int) (Double.valueOf(air1.getNumber()) - Double.valueOf(air2.getNumber()));
            }
        });

        AtomicInteger index = new AtomicInteger(1);
        for (AirInfoVO airInfoVO : airInfoVOS) {
            airInfoVO.setRankNum(String.valueOf(index.get()));
            index.getAndIncrement();
        }
    }


    private AirInfoVO getAirInfo(String k, List<String> v) {
        Double sum = new Double(0);
        for (String value : v) {
            if (value != null) {
                sum += Double.valueOf(value);
            }
        }

        AirInfoVO airInfoVO = new AirInfoVO();
        airInfoVO.setDeviceName(k);
        if (v.size() > 0) {
            airInfoVO.setNumber(String.valueOf(sum / v.size()));
        } else {
            airInfoVO.setNumber("0");
        }
        airInfoVO.setPer(String.valueOf(sum * 0.8));
        return airInfoVO;
    }

    private Map<String, List<String>> initMap(Map<String, List<String>> map, String deviceName, String value) {
        List<String> list;
        if (map.containsKey(deviceName)) {
            list = map.get(deviceName);
        } else {
            list = new ArrayList<>();
        }
        list.add(value);
        map.put(deviceName, list);
        return map;
    }


    @Override
    public AirRankVO airRank() {
        ArrayList<String> tspList = Lists.newArrayList(String.valueOf(DeviceTypeEnum.AIR_QT.getCode()));
        DateListenDeviceParamPO deviceParamPO = DateListenDeviceParamPO.builder().deviceTypeIds(tspList).build();
        List<ListenDataDetailVO> result = dataListenMapper.showDataListen(deviceParamPO);


        Map<String, List<String>> pm10 = new HashMap<>();
        Map<String, List<String>> pm10H = new HashMap<>();
        Map<String, List<String>> pm10D = new HashMap<>();
        Map<String, List<String>> pm10M = new HashMap<>();
        Map<String, List<String>> pm25H = new HashMap<>();
        Map<String, List<String>> pm25D = new HashMap<>();
        Map<String, List<String>> pm25M = new HashMap<>();

        AtomicReference<Integer> index = new AtomicReference<>(0);

        result.stream().forEach(rank -> {
            initMap(pm10, rank.getDeviceName(), rank.getPm10());
            if (index.get() < 7200) {
                initMap(pm10M, rank.getDeviceName(), rank.getPm10());
                initMap(pm25M, rank.getDeviceName(), rank.getPm25());

                if (index.get() < 240) {
                    initMap(pm10D, rank.getDeviceName(), rank.getPm10());
                    initMap(pm25D, rank.getDeviceName(), rank.getPm25());
                    if (index.get() < 12) {
                        initMap(pm10H, rank.getDeviceName(), rank.getPm10());
                        initMap(pm25H, rank.getDeviceName(), rank.getPm25());
                    }
                }
            }
            index.getAndSet(index.get() + 1);
        });

        List<AirInfoVO> pm10List = getAirList(pm10);
        List<AirInfoVO> pm10HList = getAirList(pm10H);
        List<AirInfoVO> pm10DList = getAirList(pm10D);
        List<AirInfoVO> pm10MList = getAirList(pm10M);
        List<AirInfoVO> pm25HList = getAirList(pm25H);
        List<AirInfoVO> pm25DList = getAirList(pm25D);
        List<AirInfoVO> pm25MList = getAirList(pm25M);

        AirRankVO build = AirRankVO.builder()
            .importantRank(pm10List)
            .pm10HourRank(pm10HList)
            .pm10DailyRank(pm10DList)
            .pm10MonthRank(pm10MList)
            .pm25HourRank(pm25HList)
            .pm25DailyRank(pm25DList)
            .pm25MonthRank(pm25MList).build();
        return build;
    }

    @Override
    public PageInfo<TspRankVO> tspRank(PageParam pageParam) {
        ArrayList<String> tspList = Lists.newArrayList(String.valueOf(DeviceTypeEnum.TSP.getCode()));
        DateListenDeviceParamPO deviceParamPO = DateListenDeviceParamPO.builder().deviceTypeIds(tspList).build();

        PageInfo<ListenDataDetailVO> result =
            PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize())
                .doSelectPageInfo(() ->
                    dataListenMapper.showDataListen(deviceParamPO)
                );


        RankPO rankPO = new RankPO();
        rankPO.setDeviceTypeIds(tspList);
        rankPO.setLimit(1200);
        List<ListenDataDetailVO> rankH = dataListenMapper.showDataRankListen(rankPO);
        rankPO.setLimit(2400);
        List<ListenDataDetailVO> rankD = dataListenMapper.showDataRankListen(rankPO);
        rankPO.setLimit(7200);
        List<ListenDataDetailVO> rankM = dataListenMapper.showDataRankListen(rankPO);

        Map<String, Integer> rankMapH = trans(rankH, "TSP");
        Map<String, Integer> rankMapD = trans(rankD, "TSP");
        Map<String, Integer> rankMapM = trans(rankM, "TSP");


        List<TspRankVO> tspBillVOS = result.getList().stream().map(data -> {
            TspRankVO airBillVO = new TspRankVO();

            airBillVO.setDeviceName(data.getDeviceName());
            String value = data.getTsp();
            if (StringUtils.isEmpty(value)) {
                airBillVO.setTsp("0");
            } else {
                airBillVO.setTsp(value);
            }
            if (rankMapH.containsKey(data.getDeviceCode())) {
                airBillVO.setHourRank(rankMapH.get(data.getDeviceCode()));
            } else {
                airBillVO.setHourRank(0);
            }
            if (rankMapD.containsKey(data.getDeviceCode())) {
                airBillVO.setDailyRank(rankMapD.get(data.getDeviceCode()));
            } else {
                airBillVO.setDailyRank(0);
            }
            if (rankMapM.containsKey(data.getDeviceCode())) {
                airBillVO.setMonthRank(rankMapM.get(data.getDeviceCode()));
            } else {
                airBillVO.setMonthRank(0);
            }
            return airBillVO;
        }).collect(Collectors.toList());


        Collections.sort(tspBillVOS, new Comparator<TspRankVO>() {
            @Override
            public int compare(TspRankVO air1, TspRankVO air2) {
                return Double.valueOf(air2.getTsp()).intValue() - Double.valueOf(air1.getTsp()).intValue();
            }
        });


        PageInfo<TspRankVO> pageInfo = new PageInfo<>();
        pageInfo.setList(SUBlIST2(tspBillVOS, (pageParam.getPageNum() - 1) * pageParam.getPageSize()
            , (pageParam.getPageNum() - 1) * pageParam.getPageSize() + pageParam.getPageSize()));
        pageInfo.setNextPage(result.getNextPage());
        pageInfo.setTotal(result.getTotal());
        pageInfo.setPageNum(result.getPageNum());
        return pageInfo;
    }

    @Override
    public PageInfo<TspBillVO> tspBill(PageParam<DateListenDeviceParamPO> pageParam) {

        ArrayList<String> tspList = Lists.newArrayList(String.valueOf(DeviceTypeEnum.TSP.getCode()));
        DateListenDeviceParamPO deviceParamPO = pageParam.getQueryFields();
        deviceParamPO.setDeviceTypeIds(tspList);

        PageInfo<ListenDataDetailVO> result =
            PageHelper.startPage(0, 999)
                .doSelectPageInfo(() ->
                    dataListenMapper.showDataListen(deviceParamPO)
                );

        RankPO rankPO = new RankPO();
        rankPO.setDeviceTypeIds(tspList);
        rankPO.setLimit(1200);
        List<ListenDataDetailVO> rankH = dataListenMapper.showDataRankListen(rankPO);
        rankPO.setLimit(2400);
        List<ListenDataDetailVO> rankD = dataListenMapper.showDataRankListen(rankPO);
        rankPO.setLimit(7200);
        List<ListenDataDetailVO> rankM = dataListenMapper.showDataRankListen(rankPO);

        Map<String, Integer> rankMapH = trans(rankH, "TSP");
        Map<String, Integer> rankMapD = trans(rankD, "TSP");
        Map<String, Integer> rankMapM = trans(rankM, "TSP");


        List<TspBillVO> tspBillVOS = result.getList().stream().map(data -> {
            TspBillVO airBillVO = new TspBillVO();

            airBillVO.setDeviceName(data.getDeviceName());
            String value = data.getTsp();
            if (StringUtils.isEmpty(value)) {
                airBillVO.setTsp("0");
            } else {
                airBillVO.setTsp(value);
            }
            airBillVO.setDeviceCode(data.getDeviceCode());
            if (rankMapH.containsKey(data.getDeviceCode())) {
                airBillVO.setHourRank(rankMapH.get(data.getDeviceCode()));
            } else {
                airBillVO.setHourRank(0);
            }
            if (rankMapD.containsKey(data.getDeviceCode())) {
                airBillVO.setDailyRank(rankMapD.get(data.getDeviceCode()));
            } else {
                airBillVO.setDailyRank(0);
            }
            if (rankMapM.containsKey(data.getDeviceCode())) {
                airBillVO.setMonthRank(rankMapM.get(data.getDeviceCode()));
            } else {
                airBillVO.setMonthRank(0);
            }
            return airBillVO;
        }).collect(Collectors.toList());


        Collections.sort(tspBillVOS, new Comparator<TspBillVO>() {
            @Override
            public int compare(TspBillVO air1, TspBillVO air2) {
                return Double.valueOf(air2.getTsp()).intValue() - Double.valueOf(air1.getTsp()).intValue();
            }
        });


        PageInfo<TspBillVO> pageInfo = new PageInfo<>();
        pageInfo.setList(SUBlIST(tspBillVOS, (pageParam.getPageNum() - 1) * pageParam.getPageSize()
            , (pageParam.getPageNum() - 1) * pageParam.getPageSize() + pageParam.getPageSize()));
        pageInfo.setNextPage(result.getNextPage());
        pageInfo.setTotal(result.getTotal());
        pageInfo.setPageNum(result.getPageNum());

        return pageInfo;
    }


    private List<TspRankVO> SUBlIST2(List<TspRankVO> list, int start, int end) {
        List<TspRankVO> result = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if (i >= start && i <= end) {
                result.add(list.get(i));
            }
        }
        return result;
    }


    private List<TspBillVO> SUBlIST(List<TspBillVO> list, int start, int end) {
        List<TspBillVO> result = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if (i >= start && i <= end) {
                result.add(list.get(i));
            }
        }
        return result;
    }

    @Override
    public Integer tspCount() {
        Integer count = dataListenMapper.countTsp(String.valueOf(DeviceTypeEnum.TSP.getCode()));
        return count;
    }

    @Override
    public PageInfo<AirBillVO> airBill(PageParam<AirPO> pageParam) {

        AirPO airPO = pageParam.getQueryFields();
        if (StringUtils.isBlank(airPO.getField())) {
            airPO.setField("pm10");
        }
        ArrayList<String> tspList = Lists.newArrayList(String.valueOf(DeviceTypeEnum.AIR_QT.getCode()));

        DateListenDeviceParamPO deviceParamPO = DateListenDeviceParamPO
            .builder()
            .deviceTypeIds(tspList)
            .deviceName(airPO.getDeviceName())
            .build();
        PageInfo<ListenDataDetailVO> result =
            PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize())
                .doSelectPageInfo(() ->
                    dataListenMapper.showDataListen(deviceParamPO)
                );


        RankPO rankPO = new RankPO();
        rankPO.setDeviceTypeIds(tspList);
        rankPO.setLimit(12);
        List<ListenDataDetailVO> rankH = dataListenMapper.showDataRankListen(rankPO);
        rankPO.setLimit(240);
        List<ListenDataDetailVO> rankD = dataListenMapper.showDataRankListen(rankPO);
        rankPO.setLimit(7200);
        List<ListenDataDetailVO> rankM = dataListenMapper.showDataRankListen(rankPO);

        Map<String, Integer> rankMapH = trans(rankH, airPO.getField());
        Map<String, Integer> rankMapD = trans(rankD, airPO.getField());
        Map<String, Integer> rankMapM = trans(rankM, airPO.getField());


        List<AirBillVO> airBillVOS = result.getList().stream().map(data -> {
            AirBillVO airBillVO = new AirBillVO();

            airBillVO.setDeviceUid(data.getDeviceUid());
            airBillVO.setDeviceName(data.getDeviceName());
            airBillVO.setDeviceCode(data.getDeviceCode());
            String value = "";
            switch (airPO.getField()) {
                case "pm10":
                    value = data.getTsp();
                    break;
                case "pm25":
                    value = data.getPm25();
                    break;
                case "tsp":
                    value = data.getTsp();
                    break;
                case "temp":
                    value = data.getTemp();
                    break;
                case "humidity":
                    value = data.getHumidity();
                    break;
                case "windSpeed":
                    value = data.getWindSpeed();
                    break;
                case "windDirection":
                    value = data.getWindDirection();
                    break;
                case "pa":
                    value = data.getPa();
                    break;
                default:
                    value = data.getTsp();
                    break;
            }

            airBillVO.setValue(value);
            airBillVO.setRankH(rankMapH.get(data.getDeviceCode()));
            airBillVO.setRankD(rankMapD.get(data.getDeviceCode()));
            airBillVO.setRankM(rankMapM.get(data.getDeviceCode()));

            ListenDataDetailVO dataListen = dataListenMapper.selectByDeviceId(data.getDeviceCode());
            airBillVO.setPm10(dataListen.getPm10());
            airBillVO.setPm25(dataListen.getPm25());
            return airBillVO;
        }).collect(Collectors.toList());


        Collections.sort(airBillVOS, new Comparator<AirBillVO>() {
            @Override
            public int compare(AirBillVO air1, AirBillVO air2) {
                return Double.valueOf(air1.getValue()).intValue() - Double.valueOf(air2.getValue()).intValue();
            }
        });

        PageInfo<AirBillVO> pageInfo = new PageInfo<>();
        pageInfo.setList(airBillVOS);
        pageInfo.setNextPage(result.getNextPage());
        pageInfo.setTotal(result.getTotal());
        pageInfo.setPageNum(result.getPageNum());

        return pageInfo;
    }

    @Override
    public List<ChartVO> getChart(ChartPO chartPO) {

        List<ChartVO> chartVOS = new ArrayList<>();
        if (chartPO.getField().equals("dl") || chartPO.getField().equals("yc") || chartPO.getField().equals("pl")) {
            ProdChartPO prodChartPO = new ProdChartPO();
            if (chartPO.getField().equals("dl")) {
                switch (chartPO.getDeviceCode()) {
                    case "块矿除尘器":
                        prodChartPO.setDeviceId("通道 1.高炉矿槽.LTCGLKKCCQDL");
                        break;
                    case "高炉矿槽布袋除尘器":
                        prodChartPO.setDeviceId("通道 1.烧结除尘.LTCGLKCCCQDL");
                        break;
                    default:
                        prodChartPO.setDeviceId("通道 1.高炉矿槽.LTCGLKKCCQPL");
                        break;
                }
            }
            if (chartPO.getField().equals("yc")) {
                switch (chartPO.getDeviceCode()) {
                    case "块矿除尘器":
                        prodChartPO.setDeviceId("通道 1.高炉矿槽.LTCGLKKCCQYC");
                        break;
                    case "高炉矿槽布袋除尘器":
                        prodChartPO.setDeviceId("通道 1.烧结除尘.LTCGLKCCCQYC");
                        break;
                    default:
                        prodChartPO.setDeviceId("通道 1.高炉矿槽.LTCGLKKCCQPL");
                        // todo
                        break;
                }
            }
            if (chartPO.getField().equals("pl")) {
                switch (chartPO.getDeviceCode()) {
                    case "块矿除尘器":
                        prodChartPO.setDeviceId("通道 1.高炉矿槽.LTCGLKKCCQPL");
                        break;
                    case "高炉矿槽布袋除尘器":
                        prodChartPO.setDeviceId("通道 1.烧结除尘.LTCGLKCCCQPL");
                        break;
                    default:
                        prodChartPO.setDeviceId("通道 1.高炉矿槽.LTCGLKKCCQPL");
                        break;
                }
                prodChartPO.setDeviceId("通道 1.烧结除尘.LTCGLKCCCQPL");
            }
            prodChartPO.setStartTime(chartPO.getStartTime());
            prodChartPO.setEndTime(chartPO.getEndTime());
            List<DataProd> dataProds = dataProdMapper.showDeviceDataList(prodChartPO);
            chartVOS = dataProds.stream().map(data -> {
                ChartVO chartVO = new ChartVO();
// remark就是电流和电压的位置。
                chartVO.setValue(data.getRemark());
                chartVO.setTime(Date.from(data.getCreateTime().atZone(ZoneId.systemDefault()).toInstant()));
                return chartVO;
            }).collect(Collectors.toList());
        } else {
            // 这里需要把pm25 and pm10 排除
            if ((!chartPO.getField().equals("pm25") && !chartPO.getField().equals("pm10"))
                && (!chartPO.getField().equals("tsp"))) {

                ProdChartPO prodChartPO = new ProdChartPO();
                prodChartPO.setDeviceId(chartPO.getDeviceCode());
                prodChartPO.setStartTime(chartPO.getStartTime());
                prodChartPO.setEndTime(chartPO.getEndTime());
                List<DataProd> dataProds = dataProdMapper.showDeviceDataList(prodChartPO);
                chartVOS = dataProds.stream().map(data -> {
                    ChartVO chartVO = new ChartVO();
                    chartVO.setValue(data.getRemark());
                    chartVO.setTime(Date.from(data.getCreateTime().atZone(ZoneId.systemDefault()).toInstant()));
                    return chartVO;
                }).collect(Collectors.toList());
            }
        }

        if (chartVOS.isEmpty()) {
            List<ListenDataDetailVO> list = new ArrayList<>();
            if (StringUtils.isEmpty(chartPO.getStartTime())) {
                chartPO.setStartTime(DateUtil.getPassDayS(1));
            }

            if (StringUtils.isEmpty(chartPO.getEndTime())) {
                chartPO.setEndTime(DateUtil.getCurrentDayE());
            }
            if (!chartPO.getEndTime().contains(":")) {
                chartPO.setEndTime(chartPO.getEndTime() + " 23:59:59");
            }

            if (StringUtils.isEmpty(chartPO.getDeviceCode())) {
                list = dataListenMapper.showListDateOnly(chartPO);
            } else {
                list = dataListenMapper.showListDate(chartPO);
            }

            chartVOS = list.stream().map(data -> {
                ChartVO chartVO = new ChartVO();
                if (chartPO.getField().equals("pm10")) {
                    chartVO.setValue(data.getPm10());
                }
                if (chartPO.getField().equals("pm25")) {
                    chartVO.setValue(data.getPm25());
                }
                if (chartPO.getField().equals("tsp")) {
                    chartVO.setValue(data.getTsp());
                }
                if (chartPO.getField().equals("humidity")) {
                    chartVO.setValue(data.getHumidity());
                }
                if (chartPO.getField().equals("temp")) {
                    chartVO.setValue(data.getTemp());
                }
                if (chartPO.getField().equals("speed")) {
                    chartVO.setValue(data.getWindSpeed());
                }
                if (chartPO.getField().equals("pa")) {
                    chartVO.setValue(data.getPa());
                }
                chartVO.setTime(data.getCreateTime());
                return chartVO;
            }).collect(Collectors.toList());
        }


        return chartVOS;
    }


    private Map<String, Integer> trans(List<ListenDataDetailVO> rankList, String field) {
        Map<String, Integer> map = new HashMap<>();
        List<RankDTO> rankDTOS = rankList.stream().map(rank -> {
            String value = "";
            switch (field) {
                case "pm10":
                    value = rank.getTsp();
                    break;
                case "pm25":
                    value = rank.getPm25();
                    break;
                case "tsp":
                    value = rank.getTsp();
                    break;
                case "temp":
                    value = rank.getTemp();
                    break;
                case "humidity":
                    value = rank.getHumidity();
                    break;
                case "windSpeed":
                    value = rank.getWindSpeed();
                    break;
                case "windDirection":
                    value = rank.getWindDirection();
                    break;
                case "pa":
                    value = rank.getPa();
                    break;
                default:
                    value = rank.getTsp();
                    break;
            }
            if (StringUtils.isEmpty(value)) {
                value = "0";
            }
            return new RankDTO(rank.getDeviceCode(), Double.valueOf(value));
        }).collect(Collectors.toList());
        rankDTOS.stream().sorted(Comparator.comparingDouble(RankDTO::getValue).reversed());

        int i = 0;
        for (RankDTO rankDTO : rankDTOS) {
            map.put(rankDTO.getDeviceId(), i++);
        }
        return map;
    }

    //    @Override
    public PageInfo<AirBillVO> airBill2(PageParam<AirPO> pageParam) {

        AirPO airPO = pageParam.getQueryFields();
        if (StringUtils.isBlank(airPO.getField())) {
            airPO.setField("pm10");
        }
        ArrayList<String> tspList = Lists.newArrayList(String.valueOf(DeviceTypeEnum.AIR_QT.getCode()));

        DateListenDeviceParamPO deviceParamPO = DateListenDeviceParamPO
            .builder()
            .deviceTypeIds(tspList)
            .deviceName(airPO.getDeviceName())
            .build();
        PageInfo<ListenDataDetailVO> result =
            PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize())
                .doSelectPageInfo(() ->
                    dataListenMapper.showDataListen(deviceParamPO)
                );

        List<AirBillVO> airBillVOS = getAirBill(result, airPO.getField());
        Collections.sort(airBillVOS, new Comparator<AirBillVO>() {
            @Override
            public int compare(AirBillVO air1, AirBillVO air2) {
                return air1.getRankD() - air2.getRankD();
            }
        });

        Integer i = (pageParam.getPageNum() - 1) * pageParam.getPageSize();
        for (AirBillVO rank : airBillVOS) {
            rank.setRankD(1 + i);
            rank.setRankH(1 + i);
            rank.setRankM(1 + i);
            i++;
        }

        PageInfo<AirBillVO> pageInfo = new PageInfo<>();
        pageInfo.setList(airBillVOS);
        pageInfo.setNextPage(result.getNextPage());
        pageInfo.setTotal(result.getTotal());
        pageInfo.setPageNum(result.getPageNum());

        return pageInfo;
    }

    private void proceeMap(Map<String, List<String>> data, Map<String, List<String>> dataH, Map<String, List<String>> dataD, Map<String, List<String>> dataM, String name, String value, AtomicReference<Integer> index) {

        initMap(data, name, value);
        if (index.get() < 7200) {
            initMap(dataM, name, value);
            if (index.get() < 240) {
                initMap(dataD, name, value);
                if (index.get() < 12) {
                    initMap(dataH, name, value);
                }
            }
        }
        index.getAndSet(index.get() + 1);
    }

    private List<AirBillVO> getAirBill(PageInfo<ListenDataDetailVO> result, String field) {

        Map<String, List<String>> data = new HashMap<>();
        Map<String, List<String>> dataH = new HashMap<>();
        Map<String, List<String>> dataD = new HashMap<>();
        Map<String, List<String>> dataM = new HashMap<>();
        AtomicReference<Integer> index = new AtomicReference<>(0);
        result.getList().stream().forEach(rank -> {
            switch (field) {
                case "pm10":
                    proceeMap(data, dataH, dataD, dataM, rank.getDeviceName(), rank.getPm10(), index);
                    break;
                case "pm25":
                    proceeMap(data, dataH, dataD, dataM, rank.getDeviceName(), rank.getPm25(), index);
                    break;
                case "tsp":
                    proceeMap(data, dataH, dataD, dataM, rank.getDeviceName(), rank.getTsp(), index);
                    break;
                case "temp":
                    proceeMap(data, dataH, dataD, dataM, rank.getDeviceName(), rank.getTemp(), index);
                    break;
                case "humidity":
                    proceeMap(data, dataH, dataD, dataM, rank.getDeviceName(), rank.getHumidity(), index);
                    break;
                case "windSpeed":
                    proceeMap(data, dataH, dataD, dataM, rank.getDeviceName(), rank.getWindSpeed(), index);
                    break;
                case "windDirection":
                    proceeMap(data, dataH, dataD, dataM, rank.getDeviceName(), rank.getWindDirection(), index);
                    break;
                case "pa":
                    proceeMap(data, dataH, dataD, dataM, rank.getDeviceName(), rank.getPa(), index);
                    break;
                default:
                    break;
            }
        });
        Map<String, AirBillVO> airBillVOMap = new HashMap<>();
        List<AirInfoVO> dataList = getAirList(data);
        List<AirInfoVO> dataHList = getAirList(dataH);
        List<AirInfoVO> dataDList = getAirList(dataD);
        List<AirInfoVO> dataMList = getAirList(dataM);

        List<AirBillVO> airRankVOS = new ArrayList<>();
        dataList.forEach(dataL -> {
            AirBillVO airRankVO;
            if (airBillVOMap.containsKey(dataL.getDeviceName())) {
                airRankVO = airBillVOMap.get(dataL.getDeviceName());
                airRankVO.setValue(dataL.getNumber());
            } else {
                airRankVO = new AirBillVO();
                airRankVO.setValue(dataL.getNumber());
                airRankVO.setDeviceName(dataL.getDeviceName());
                airRankVO.setDeviceUid(dataL.getDeviceUid());
            }
            airBillVOMap.put(dataL.getDeviceName(), airRankVO);
        });

        dataHList.forEach(dataL -> {
            AirBillVO airRankVO;
            if (airBillVOMap.containsKey(dataL.getDeviceName())) {
                airRankVO = airBillVOMap.get(dataL.getDeviceName());
                airRankVO.setRankH(Integer.valueOf(dataL.getRankNum()));
            } else {
                airRankVO = new AirBillVO();
                airRankVO.setDeviceName(dataL.getDeviceName());
                airRankVO.setRankH(Integer.valueOf(dataL.getRankNum()));
                airRankVO.setDeviceUid(dataL.getDeviceUid());
            }
            airBillVOMap.put(dataL.getDeviceName(), airRankVO);
        });

        dataDList.forEach(dataL -> {
            AirBillVO airRankVO;
            if (airBillVOMap.containsKey(dataL.getDeviceName())) {
                airRankVO = airBillVOMap.get(dataL.getDeviceName());
                airRankVO.setRankD(Integer.valueOf(dataL.getRankNum()));
            } else {
                airRankVO = new AirBillVO();
                airRankVO.setDeviceName(dataL.getDeviceName());
                airRankVO.setRankD(Integer.valueOf(dataL.getRankNum()));
                airRankVO.setDeviceUid(dataL.getDeviceUid());
            }
            airBillVOMap.put(dataL.getDeviceName(), airRankVO);
        });

        dataMList.forEach(dataL -> {
            AirBillVO airRankVO;
            if (airBillVOMap.containsKey(dataL.getDeviceName())) {
                airRankVO = airBillVOMap.get(dataL.getDeviceName());
                airRankVO.setRankM(Integer.valueOf(dataL.getRankNum()));
            } else {
                airRankVO = new AirBillVO();
                airRankVO.setDeviceName(dataL.getDeviceName());
                airRankVO.setRankM(Integer.valueOf(dataL.getRankNum()));
                airRankVO.setDeviceUid(dataL.getDeviceUid());
            }
            airBillVOMap.put(dataL.getDeviceName(), airRankVO);
        });
        airBillVOMap.forEach((k, v) -> {
            airRankVOS.add(v);
        });
        return airRankVOS;
    }

    @Override
    public ListenDeviceNumVO listenDeviceNum() {
//ArrayList<Integer> sumCount = Lists.newArrayList(11, 12);
//int sum = deviceServiceImpl.countDeviceTypeIn(sumCount);

        int tspNum = deviceServiceImpl.countDeviceType(DeviceTypeEnum.TSP.getCode());
        int cemsNum = deviceServiceImpl.countDeviceType(DeviceTypeEnum.ECMS.getCode());
        int airQt = deviceServiceImpl.countDeviceType(DeviceTypeEnum.AIR_QT.getCode());

        int sum = airQt + tspNum + cemsNum;

        ListenDeviceNumVO deviceNumVO = ListenDeviceNumVO.builder()
            .tspNum(tspNum)
            .airQtNum(airQt)
            .cemsNum(cemsNum)
            .listenDeviceSum(sum).build();
        return deviceNumVO;
    }

    @Override
    public PageInfo<DeviceVO> listenDeviceList(PageParam<DeviceParamPO> param) {

        DeviceParamPO deviceParamPO = param.getQueryFields();
        if (CollectionUtils.isEmpty(deviceParamPO.getDeviceTypeIds())) {
            deviceParamPO.setDeviceTypeIds(Lists.newArrayList(String.valueOf(DeviceTypeEnum.TSP.getCode()), String.valueOf(DeviceTypeEnum.ECMS.getCode())));
        }

        PageInfo<DeviceVO> result =
            PageHelper.startPage(param.getPageNum(), param.getPageSize())
                .doSelectPageInfo(() ->
                    deviceMapper.getDeviceList(deviceParamPO)
                );
        return result;
    }


}
